package handlers

import (
	"restaurant-system/config"
	"restaurant-system/internal/models"
	"restaurant-system/pkg/payment"

	"github.com/gin-gonic/gin"
)

// 创建支付请求
type CreatePaymentRequest struct {
	OrderID       uint    `json:"order_id" binding:"required"`
	PaymentMethod string  `json:"payment_method" binding:"required,oneof=alipay wechat credit_card"`
	Amount        float64 `json:"amount" binding:"required,gt=0"`
}

// 创建支付
func CreatePayment(c *gin.Context) {
	var req CreatePaymentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 检查订单是否存在
	var order models.Order
	if err := config.DB.First(&order, req.OrderID).Error; err != nil {
		c.JSON(404, gin.H{"error": "订单不存在"})
		return
	}

	// 检查订单状态
	if order.Status != "pending" {
		c.JSON(400, gin.H{"error": "订单状态不正确"})
		return
	}

	// 检查支付金额
	if req.Amount != order.TotalAmount {
		c.JSON(400, gin.H{"error": "支付金额不正确"})
		return
	}

	// 创建支付记录
	paymentRecord := models.Payment{
		OrderID:       req.OrderID,
		Amount:        req.Amount,
		PaymentMethod: req.PaymentMethod,
		Status:        "pending",
	}

	if err := config.DB.Create(&paymentRecord).Error; err != nil {
		c.JSON(500, gin.H{"error": "创建支付记录失败"})
		return
	}

	// 调用支付接口
	payResult, err := payment.ProcessPayment(req.PaymentMethod, paymentRecord.ID, req.Amount)
	if err != nil {
		c.JSON(500, gin.H{"error": "支付处理失败"})
		return
	}

	c.JSON(200, gin.H{
		"message": "创建支付成功",
		"payment": paymentRecord,
		"pay_url": payResult.PayURL, // 支付链接
	})
}

// 支付回调
func PaymentCallback(c *gin.Context) {
	paymentMethod := c.Param("method")
	var payResult payment.PayResult

	switch paymentMethod {
	case "alipay":
		payResult = payment.HandleAlipayCallback(c.Request)
	case "wechat":
		payResult = payment.HandleWechatCallback(c.Request)
	default:
		c.JSON(400, gin.H{"error": "不支持的支付方式"})
		return
	}

	if !payResult.Success {
		c.JSON(400, gin.H{"error": "支付回调验证失败"})
		return
	}

	// 开启事务
	tx := config.DB.Begin()

	var payRecord models.Payment
	if err := tx.First(&payRecord, payResult.PaymentID).Error; err != nil {
		tx.Rollback()
		c.JSON(404, gin.H{"error": "支付记录不存在"})
		return
	}

	// 更新支付状态
	if err := tx.Model(&payRecord).Updates(map[string]interface{}{
		"status":   "success",
		"trade_no": payResult.TradeNo,
	}).Error; err != nil {
		tx.Rollback()
		c.JSON(500, gin.H{"error": "更新支付状态失败"})
		return
	}

	// 更新订单状态
	if err := tx.Model(&models.Order{}).Where("id = ?", payRecord.OrderID).
		Update("status", "paid").Error; err != nil {
		tx.Rollback()
		c.JSON(500, gin.H{"error": "更新订单状态失败"})
		return
	}

	tx.Commit()
	c.JSON(200, gin.H{"message": "支付成功"})
}

// 申请退款
type RefundRequest struct {
	PaymentID uint    `json:"payment_id" binding:"required"`
	Amount    float64 `json:"amount" binding:"required,gt=0"`
	Reason    string  `json:"reason" binding:"required"`
}

func CreateRefund(c *gin.Context) {
	var req RefundRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 检查支付记录
	var payRecord models.Payment
	if err := config.DB.First(&payRecord, req.PaymentID).Error; err != nil {
		c.JSON(404, gin.H{"error": "支付记录不存在"})
		return
	}

	// 检查退款金额
	if req.Amount > payRecord.Amount-payRecord.RefundAmount {
		c.JSON(400, gin.H{"error": "退款金额超过可退金额"})
		return
	}

	// 创建退款记录
	refund := models.Refund{
		PaymentID: req.PaymentID,
		Amount:    req.Amount,
		Reason:    req.Reason,
		Status:    "pending",
	}

	if err := config.DB.Create(&refund).Error; err != nil {
		c.JSON(500, gin.H{"error": "创建退款记录失败"})
		return
	}

	// 调用退款接口
	refundResult, err := payment.ProcessRefund(payRecord.PaymentMethod, payRecord.TradeNo, refund.ID, req.Amount)
	if err != nil {
		c.JSON(500, gin.H{"error": "退款处理失败"})
		return
	}

	c.JSON(200, gin.H{
		"message": "申请退款成功",
		"refund":  refund,
		"result":  refundResult,
	})
}
